/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Clases;

import java.util.ArrayList;

/**
 *
 * @author hC4stillo
 */
public class ModeloPolinomial  {
    public Comun comun;
    public ArrayList<Object> x;
    public ArrayList<Object> y;
    public ArrayList<Object> abc;
    public String r;
    public String rCuadrada;
    public String sexy;
    public ModeloPolinomial(ArrayList<Object> x, ArrayList<Object> y)
    {
        this.abc = new ArrayList();
        this.x=x;
        this.y=y;
        this.comun = new Comun(x,y);
    }
    public float sumXCubo()
    {
        float sumatoriaXCubo = 0;
        for(int i = 0; i< this.x.size();i++)
        {
            float temp = (float) Math.pow(Float.parseFloat(this.x.get(i).toString()), 3);
            sumatoriaXCubo =sumatoriaXCubo + temp;
        }
        return sumatoriaXCubo;
    }

    public float sumXCuarta()
    {
        float sumatoriaXCuarta = 0;
        for(int i = 0; i< this.x.size();i++)
        {
            float temp = (float) Math.pow(Float.parseFloat(this.x.get(i).toString()), 4);
            sumatoriaXCuarta =sumatoriaXCuarta + temp;
        }
        return sumatoriaXCuarta;
    }

    public float sumXCuadPorY()
    {
        float sumatoriaXCPorY = 0;
        ArrayList<Object> xCuadrado = this.comun.getXCuadrado();
        for(int i = 0; i< this.x.size();i++)
        {
            float temp = Float.parseFloat(xCuadrado.get(i).toString()) * Float.parseFloat(this.y.get(i).toString());
            sumatoriaXCPorY =sumatoriaXCPorY + temp;
        }
        return sumatoriaXCPorY;
    }
    public float getDeterminante(Object[][] mat)
    {
        float det=0;
        float temp1 = Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[1][1].toString())*Float.parseFloat(mat[2][2].toString());
        temp1=temp1+(Float.parseFloat(mat[0][1].toString())*Float.parseFloat(mat[1][2].toString())*Float.parseFloat(mat[2][0].toString()));
        temp1=temp1+(Float.parseFloat(mat[0][2].toString())*Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[2][1].toString()));
        float temp2 = Float.parseFloat(mat[0][2].toString())*Float.parseFloat(mat[1][1].toString())*Float.parseFloat(mat[2][0].toString());
        temp2=temp2+(Float.parseFloat(mat[0][1].toString())*Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[2][2].toString()));
        temp2=temp2+(Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[1][2].toString())*Float.parseFloat(mat[2][1].toString()));
        det = temp1-temp2;
        return det;
    }
    public Object[][] matrixInversa(Object[][] mat)
    {
        Object[][] inversa = new Object[3][3];
        float determinante = this.getDeterminante(mat);
        inversa[0][0]=1*((Float.parseFloat(mat[1][1].toString())*Float.parseFloat(mat[2][2].toString()))+(Float.parseFloat(mat[1][2].toString())*Float.parseFloat(mat[2][1].toString())));
        inversa[1][0]=-1*((Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[2][2].toString()))+(Float.parseFloat(mat[1][2].toString())*Float.parseFloat(mat[0][0].toString())));
        inversa[2][0]=1*((Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[2][1].toString()))+(Float.parseFloat(mat[1][1].toString())*Float.parseFloat(mat[2][1].toString())));
        inversa[0][1]=-1*((Float.parseFloat(mat[0][1].toString())*Float.parseFloat(mat[2][2].toString()))+(Float.parseFloat(mat[0][2].toString())*Float.parseFloat(mat[2][1].toString())));
        inversa[1][1]=1*((Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[2][2].toString()))+(Float.parseFloat(mat[2][0].toString())*Float.parseFloat(mat[0][2].toString())));
        inversa[2][1]=-1*((Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[2][1].toString()))+(Float.parseFloat(mat[0][1].toString())*Float.parseFloat(mat[2][0].toString())));
        inversa[0][2]=1*((Float.parseFloat(mat[0][1].toString())*Float.parseFloat(mat[1][2].toString()))+(Float.parseFloat(mat[0][2].toString())*Float.parseFloat(mat[1][1].toString())));
        inversa[1][2]=-1*((Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[1][2].toString()))+(Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[1][2].toString())));
        inversa[2][2]=1*((Float.parseFloat(mat[0][0].toString())*Float.parseFloat(mat[1][1].toString()))+(Float.parseFloat(mat[1][0].toString())*Float.parseFloat(mat[0][1].toString())));
        for(int i =0;i<3;i++)
        {
            for(int j = 0;j<3;j++)
            {
                inversa[i][j]=Float.parseFloat(inversa[i][j].toString())*determinante;
                System.out.println(inversa[i][j]);
            }
        }

        return inversa;
    }
    public Object[][] multiplicar(Object[][] matrixI)
    {
        ModeloLineal ml = new ModeloLineal(this.x,this.y);
        Object[][] resp = new Object[3][1];
        Object[][] mat2 = new Object[3][1];
        mat2[0][0]=ml.sumatoriaY();
        mat2[1][0]=ml.sumatoriaXY();
        mat2[2][0]=this.sumXCuadPorY();
        float temp = 0;
        for(int i = 0;i<3;i++)
        {
            for(int j = 0;j<3;j++)
            {
                temp=temp+(Float.parseFloat(matrixI[i][j].toString())*Float.parseFloat(mat2[j][0].toString()));
            }
            resp[i][0]=temp;
            temp=0;
        }
        System.out.println("a="+resp[2][0]+", b="+resp[1][0]+", c="+resp[0][0]);
        return resp;
    }
    public Object[][] setABC()
    {
        ModeloLineal ml = new ModeloLineal(this.x,this.y);
        Object[][] matrix = new Object[3][3];
        Object[][] matrixI = new Object[3][3];
        //esta fila es igual a la sumatoria de y
        matrix[0][0]=this.x.size();
        matrix[0][1]=ml.sumatoriaX();
        matrix[0][2]=ml.sumatoriaXCuadrado();

        //esta fila es igual a la sumatoria de xy
        matrix[1][0]=ml.sumatoriaX();
        matrix[1][1]=ml.sumatoriaXCuadrado();
        matrix[1][2]=this.sumXCubo();
        //este es igual a x cuadrado por y
        matrix[2][0]=ml.sumatoriaXCuadrado();
        matrix[2][1]=this.sumXCubo();
        matrix[2][2]=this.sumXCuarta();
        matrixI=this.matrixInversa(matrix);
        return this.multiplicar(matrixI);
    }
    //ax^2+bx+c (0,0)-c;(1,0)-b;(2,0)-a
    public ArrayList<Object> getYCalculada()
    {
        ArrayList<Object> retorno = new ArrayList();
        ArrayList<Object> xCuad = this.comun.getXCuadrado();
        Object[][] constantes = this.setABC();
        for(int i = 0;i<this.x.size();i++)
        {
            retorno.add((Float.parseFloat(xCuad.get(i).toString())*Float.parseFloat(constantes[2][0].toString()))+(Float.parseFloat(constantes[1][0].toString())*Float.parseFloat(this.x.get(i).toString())));
        }
        return retorno;
    }
    public void resolver()
    {
        ModeloLineal ml = new ModeloLineal(this.x,this.y);
        ml.calcularR(this.getYCalculada());
        this.rCuadrada=ml.rCuadrada;
        this.r=ml.r;
        ml.calcularSexy(this.getYCalculada());
        this.sexy=ml.sexy;
    }
}
